//
// Created by Moonbreeze on 2015/12/18.
//
#include "JavaClass.h"
#include "ObjectHeap.h"
#include "ClassHeap.h"
#include <string.h>

ObjectHeap::ObjectHeap()
:m_nNextObjectID(1)
{ }

ObjectHeap::~ObjectHeap() { }

Object ObjectHeap::CreateObject(JavaClass *pClass) {
    Object object;
    object.heapPtr = 0;
    object.type = 0;

    if (pClass == NULL) return object;
    u4 osize = pClass->GetObjectFieldCount() + 1;// +1 is the class pointer

    Variable* obj = new Variable[osize];

    memset(obj,0,sizeof(Variable) * osize);
    object.heapPtr = m_nNextObjectID;
    m_nNextObjectID++;
    obj[0].ptrValue = (void*)pClass;

    m_ObjectMap.insert(std::make_pair(object.heapPtr,obj));

    return object;
}

Object ObjectHeap::CreateStringObject(std::string pStrValue, ClassHeap *pClassHeap) {
    Object object;
    object.heapPtr = 0;
    object.type = 0;

    if (pClassHeap == NULL) return object;
    JavaClass* pClass = pClassHeap->GetClass(std::string("java/lang/String"));

    if (pClass == NULL) return object;
    
    object = CreateObject(pClass);
    Variable* pVar = this->GetObjectPointer(object);
    if(pVar == NULL) return object;
	int len = pStrValue.size() ;
    char* temp = new char[len];
    memcpy(temp, pStrValue.c_str(), pStrValue.size());
	temp[len] = '\0';
    pVar[1].ptrValue = temp;
    return object;
}

bool ObjectHeap::CreateObjectArray(JavaClass *pClass, u4 count, Object &object) {
    Variable* pVar = new Variable[count+1];

    memset(pVar,0, sizeof(Variable) * (count+1));
    pVar[0].ptrValue = pClass;

    object.heapPtr = m_nNextObjectID;
    m_nNextObjectID++;

    m_ObjectMap.insert(std::make_pair(object.heapPtr,pVar));
    return true;
}

Variable* ObjectHeap::GetObjectPointer(Object object) {

    std::map<int,Variable*>::iterator result = m_ObjectMap.find(object.heapPtr);
    if(result != m_ObjectMap.end()){
        return result->second;
    }else{
        return NULL;
    }
}

Object ObjectHeap::CreateNewArray(u1 type, i4 count) {
    Variable* obj = new Variable[count+1];
    Object object;
    object.heapPtr = 0;
    object.type = type;

    memset(obj,0, sizeof(Variable)*(count + 1));
    object.heapPtr = m_nNextObjectID;
    m_nNextObjectID++;
    obj[0].intValue = type;

    m_ObjectMap.insert(std::make_pair(object.heapPtr,obj));

    return object;
}